/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package managedbean.MRP.ProductionPlan;

import entity.MRP.ProductionPlan.PlannedMonthlyDemand;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import session.stateless.MRP.ProductionPlan.MonthlyProductionPlanBeanLocal;
import session.stateless.MRP.SaleForecast.SaleForecastBeanLocal;

/**
 *
 * @author zhozho
 */
@ManagedBean(name="generateSalesOperationPlan")
@ViewScoped
public class AddProductionPlanManagerBean implements Serializable{
  
    private String startMonth;
    private String endMonth;
    private String startMonthView;
    private String endMonthView;
    private List<String> startMonths = new ArrayList<String>();
    private List<String> endMonths = new ArrayList<String>();    
    private List<String> monthList;
    private List<PlannedMonthlyDemand> monthlyData;
    private Double breakDownA;
    private Double breakDownB;
    private Double breakDownC;
    private Double breakDownD;
    private Boolean showFieldsetSalesForecast = false;
    private Boolean showChoice = true;
    private Boolean showView = false;
    private Boolean showAdd = false;
    private String statusMessage;
    private String statusMessage1;
    private String statusMessage2;

    
    @EJB
    MonthlyProductionPlanBeanLocal plannedMonthlyDemandBeanLocal;
    @EJB
    SaleForecastBeanLocal saleForecastBeanLocal;
    
            
    //HARD CODE DATA
    private List<PlannedMonthlyDemand> database = new ArrayList<PlannedMonthlyDemand>();  
        
    
    /** Creates a new instance of AddProductionPlanManagerBean */
    public AddProductionPlanManagerBean() {
        monthlyData = new ArrayList<PlannedMonthlyDemand>();
        
    }
    
    
    public void initView(ActionEvent event) {
        startMonths.clear();
        endMonths.clear();
        monthList = plannedMonthlyDemandBeanLocal.createMonthList();
        for (int i = 0; i < monthList.size()-2; ++i)
        {
            int temp = Integer.parseInt(monthList.get(i).substring(0, monthList.get(i).length() - 5));
            if ((temp == 1) || (temp == 4) || (temp == 7) || (temp == 10))
            {
                startMonths.add(monthList.get(i));
                endMonths.add(monthList.get(i+2));
            }
        }
        
        if (database.isEmpty()) {
            database = plannedMonthlyDemandBeanLocal.getPlannedMonthlyDemands();
            
        }
        if (database.isEmpty()) {
            database = new ArrayList<PlannedMonthlyDemand>();
            for (int i = 0; i < 12; i++)
            {
                database.add(plannedMonthlyDemandBeanLocal.createPlannedMonthlyDemand(monthList.get(i), null, null, null, null, null, null, null, null, null));
            }
        }
    }
    
    public void retrieveMonthlyData(ActionEvent event) {
        monthlyData.clear();
        //run from start month to end month
        int startIndex = monthList.indexOf(startMonth);
        int endIndex = monthList.indexOf(endMonth);
        
        if (startIndex > endIndex)
        {
            statusMessage = "Invalid Date Range. Please reselect.";
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, statusMessage, ""));
   
        }
        else {
            for (int i = startIndex; i <= endIndex; i++)
            {
                monthlyData.add(plannedMonthlyDemandBeanLocal.findByMonth(monthList.get(i)));

            }

            breakDownA = monthlyData.get(0).getBreakDownA();
            breakDownB = monthlyData.get(0).getBreakDownB();
            breakDownC = monthlyData.get(0).getBreakDownC();
            breakDownD = monthlyData.get(0).getBreakDownD();

            showFieldsetSalesForecast = true;
        }
    }
    
    public void refresh(ActionEvent event)
    {     
        int startIndex = monthList.indexOf(startMonth);
        int endIndex = monthList.indexOf(endMonth);
        statusMessage = "";
        statusMessage1 = "";
        statusMessage2 = "";
        
        
        for (int i = startIndex; i <= endIndex; i++)
        {
            if ((breakDownA < 0) || (breakDownB < 0) || (breakDownC < 0) || (breakDownD < 0))
            {
                statusMessage1 = "Breakdown Percentage cannot be smaller than zero.";
            }
            else if (monthlyData.get(i-startIndex).getProductionPlan() <= 0)
            {
                statusMessage2 = "Production Plan cannot be smaller than zero.";
            }
            else
            {
                monthlyData.get(i-startIndex).setBreakDownA(breakDownA);
                monthlyData.get(i-startIndex).setBreakDownB(breakDownB);
                monthlyData.get(i-startIndex).setBreakDownC(breakDownC);
                monthlyData.get(i-startIndex).setBreakDownD(breakDownD);

                monthlyData.get(i-startIndex).setProductionPlanA(Math.round((double) monthlyData.get(i-startIndex).getProductionPlan() * monthlyData.get(i-startIndex).getBreakDownA() / 100));
                Long previousInventoryA;
                if (i == 0){
                    //inventory of the current month - 1

                    //TESTING
                    previousInventoryA = new Long(0);
                }
                else if (i - startIndex == 0) {
                    previousInventoryA = plannedMonthlyDemandBeanLocal.findByMonth(monthList.get(i-1)).getInventoryA();
                }
                else {
                    previousInventoryA = monthlyData.get(i-startIndex-1).getInventoryA();
                }

                monthlyData.get(i-startIndex).setInventoryA(plannedMonthlyDemandBeanLocal.calculateInventory(monthlyData.get(i-startIndex).getSaleForecastA(), monthlyData.get(i-startIndex).getProductionPlanA(), previousInventoryA));

                /************/
                monthlyData.get(i-startIndex).setProductionPlanB(Math.round((double) monthlyData.get(i-startIndex).getProductionPlan() * monthlyData.get(i-startIndex).getBreakDownB() / 100));
                Long previousInventoryB;
                if (i == 0){
                    //inventory of the current month - 1

                    //TESTING
                    previousInventoryB = new Long(0);
                }
                else if (i - startIndex == 0) {
                    previousInventoryB = plannedMonthlyDemandBeanLocal.findByMonth(monthList.get(i-1)).getInventoryB();
                }
                else {
                    previousInventoryB = monthlyData.get(i-startIndex-1).getInventoryB();
                }

                monthlyData.get(i-startIndex).setInventoryB(plannedMonthlyDemandBeanLocal.calculateInventory(monthlyData.get(i-startIndex).getSaleForecastB(), monthlyData.get(i-startIndex).getProductionPlanB(), previousInventoryB));

                /***********************/
                monthlyData.get(i-startIndex).setProductionPlanC(Math.round((double) monthlyData.get(i-startIndex).getProductionPlan() * monthlyData.get(i-startIndex).getBreakDownC() / 100));
                Long previousInventoryC;
                if (i == 0){
                    //inventory of the current month - 1

                    //TESTING
                    previousInventoryC = new Long(0);
                }
                else if (i - startIndex == 0) {
                    previousInventoryC = plannedMonthlyDemandBeanLocal.findByMonth(monthList.get(i-1)).getInventoryC();
                }
                else {
                    previousInventoryC = monthlyData.get(i-startIndex-1).getInventoryC();
                }

                monthlyData.get(i-startIndex).setInventoryC(plannedMonthlyDemandBeanLocal.calculateInventory(monthlyData.get(i-startIndex).getSaleForecastC(), monthlyData.get(i-startIndex).getProductionPlanC(), previousInventoryC));

                /************************/
                monthlyData.get(i-startIndex).setProductionPlanD(Math.round((double) monthlyData.get(i-startIndex).getProductionPlan() * monthlyData.get(i-startIndex).getBreakDownD() / 100));
                Long previousInventoryD;
                if (i == 0){
                    //inventory of the current month - 1

                    //TESTING
                    previousInventoryD = new Long(0);
                }
                else if (i - startIndex == 0) {
                    previousInventoryD = plannedMonthlyDemandBeanLocal.findByMonth(monthList.get(i-1)).getInventoryD();
                }
                else {
                    previousInventoryD = monthlyData.get(i-startIndex-1).getInventoryD();
                }

                monthlyData.get(i-startIndex).setInventoryD(plannedMonthlyDemandBeanLocal.calculateInventory(monthlyData.get(i-startIndex).getSaleForecastD(), monthlyData.get(i-startIndex).getProductionPlanD(), previousInventoryD));

                if ((monthlyData.get(i-startIndex).getInventoryA() < 0) || (monthlyData.get(i-startIndex).getInventoryB() < 0)
                        || (monthlyData.get(i-startIndex).getInventoryC() < 0) ||(monthlyData.get(i-startIndex).getInventoryD() < 0))
                {
                    statusMessage = "Inventory cannot be smaller than zero.";
                }
            }
        }
        if (statusMessage2.compareTo("") != 0)
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, statusMessage2, ""));
        if (statusMessage1.compareTo("") != 0)
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, statusMessage1, ""));
        if (statusMessage.compareTo("") != 0)
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, statusMessage, ""));
        
    }
    
    public void generate(ActionEvent event)  throws IOException
    {
        refresh(null);
        if ((statusMessage.compareTo("") == 0) && (statusMessage1.compareTo("") == 0) && (statusMessage2.compareTo("") == 0))
        {
            for (int i = 0; i < monthlyData.size(); i++)
            {
                String month = monthlyData.get(i).getMonthName();
                int year = Integer.parseInt(month.substring(month.length() - 4));
                plannedMonthlyDemandBeanLocal.updatePlannedMonthlyDemand(monthlyData.get(i).getId(), monthlyData.get(i).getProductionPlan(), 
                        monthlyData.get(i).getInventoryA(), monthlyData.get(i).getInventoryB(), monthlyData.get(i).getInventoryC(), monthlyData.get(i).getInventoryD(), 
                        monthlyData.get(i).getBreakDownA(), monthlyData.get(i).getBreakDownB(), monthlyData.get(i).getBreakDownC(), monthlyData.get(i).getBreakDownD());
            }

            FacesContext.getCurrentInstance().getExternalContext().getFlash().put("startMonth", monthlyData.get(0).getMonthName());
            FacesContext.getCurrentInstance().getExternalContext().getFlash().put("endMonth", monthlyData.get(monthlyData.size()-1).getMonthName());
            FacesContext.getCurrentInstance().getExternalContext().redirect("generateMonthlyProductionPlan.xhtml");
        }
    }
    public void showView(ActionEvent event)
    {
        showView = true;
        showChoice= false;
    }
    
    public void showAdd(ActionEvent event)
    {
        showAdd = true;
        showChoice= false;
    }
    
    public void view(ActionEvent event)  throws IOException
    {
        int startIndex = monthList.indexOf(startMonthView);
        int endIndex = monthList.indexOf(endMonthView);
        
        if (startIndex > endIndex)
        {
            statusMessage = "Invalid Date Range. Please reselect.";
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, statusMessage, ""));
   
        }
        else {
            FacesContext.getCurrentInstance().getExternalContext().getFlash().put("startMonth", startMonthView);
            FacesContext.getCurrentInstance().getExternalContext().getFlash().put("endMonth", endMonthView);
            FacesContext.getCurrentInstance().getExternalContext().redirect("generateMonthlyProductionPlan.xhtml");
        }
    }



    public List<PlannedMonthlyDemand> getDatabase() {
        return database;
    }

    public void setDatabase(List<PlannedMonthlyDemand> database) {
        this.database = database;
    }


    public String getEndMonth() {
        return endMonth;
    }

    public void setEndMonth(String endMonth) {
        this.endMonth = endMonth;
    }

    public String getStartMonth() {
        return startMonth;
    }

    public void setStartMonth(String startMonth) {
        this.startMonth = startMonth;
    }

    public List<String> getEndMonths() {
        return endMonths;
    }

    public void setEndMonths(List<String> endMonths) {
        this.endMonths = endMonths;
    }

    public List<PlannedMonthlyDemand> getMonthlyData() {
        return monthlyData;
    }

    public void setMonthlyData(List<PlannedMonthlyDemand> monthlyData) {
        this.monthlyData = monthlyData;
    }

    public List<String> getStartMonths() {
        return startMonths;
    }

    public void setStartMonths(List<String> startMonths) {
        this.startMonths = startMonths;
    }

    public List<String> getMonthList() {
        return monthList;
    }

    public void setMonthList(List<String> monthList) {
        this.monthList = monthList;
    }

    public Double getBreakDownA() {
        return breakDownA;
    }

    public void setBreakDownA(Double breakDownA) {
        this.breakDownA = breakDownA;
    }

    public Double getBreakDownB() {
        return breakDownB;
    }

    public void setBreakDownB(Double breakDownB) {
        this.breakDownB = breakDownB;
    }

    public Double getBreakDownC() {
        return breakDownC;
    }

    public void setBreakDownC(Double breakDownC) {
        this.breakDownC = breakDownC;
    }

    public Double getBreakDownD() {
        return breakDownD;
    }

    public void setBreakDownD(Double breakDownD) {
        this.breakDownD = breakDownD;
    }

    public Boolean getShowFieldsetSalesForecast() {
        return showFieldsetSalesForecast;
    }

    public void setShowFieldsetSalesForecast(Boolean showFieldsetSalesForecast) {
        this.showFieldsetSalesForecast = showFieldsetSalesForecast;
    }

    public String getStatusMessage() {
        return statusMessage;
    }

    public void setStatusMessage(String statusMessage) {
        this.statusMessage = statusMessage;
    }

    public String getEndMonthView() {
        return endMonthView;
    }

    public void setEndMonthView(String endMonthView) {
        this.endMonthView = endMonthView;
    }

    public MonthlyProductionPlanBeanLocal getPlannedMonthlyDemandBeanLocal() {
        return plannedMonthlyDemandBeanLocal;
    }

    public void setPlannedMonthlyDemandBeanLocal(MonthlyProductionPlanBeanLocal plannedMonthlyDemandBeanLocal) {
        this.plannedMonthlyDemandBeanLocal = plannedMonthlyDemandBeanLocal;
    }

    public SaleForecastBeanLocal getSaleForecastBeanLocal() {
        return saleForecastBeanLocal;
    }

    public void setSaleForecastBeanLocal(SaleForecastBeanLocal saleForecastBeanLocal) {
        this.saleForecastBeanLocal = saleForecastBeanLocal;
    }

    public String getStartMonthView() {
        return startMonthView;
    }

    public void setStartMonthView(String startMonthView) {
        this.startMonthView = startMonthView;
    }

    public String getStatusMessage1() {
        return statusMessage1;
    }

    public void setStatusMessage1(String statusMessage1) {
        this.statusMessage1 = statusMessage1;
    }

    public String getStatusMessage2() {
        return statusMessage2;
    }

    public void setStatusMessage2(String statusMessage2) {
        this.statusMessage2 = statusMessage2;
    }

    public Boolean getShowAdd() {
        return showAdd;
    }

    public void setShowAdd(Boolean showAdd) {
        this.showAdd = showAdd;
    }

    public Boolean getShowView() {
        return showView;
    }

    public void setShowView(Boolean showView) {
        this.showView = showView;
    }

    public Boolean getShowChoice() {
        return showChoice;
    }

    public void setShowChoice(Boolean showChoice) {
        this.showChoice = showChoice;
    }


    
}
       
        
    